package com.emapp.lccode.activity

import android.annotation.SuppressLint
import android.content.Intent
import android.graphics.Color
import android.location.Location
import android.os.Bundle
import android.provider.Settings
import android.view.View
import androidx.lifecycle.viewModelScope
import com.amap.api.location.AMapLocationClient
import com.amap.api.maps.AMap
import com.amap.api.maps.CameraUpdateFactory
import com.amap.api.maps.model.LatLng
import com.amap.api.maps.model.Marker
import com.amap.api.maps.model.MarkerOptions
import com.amap.api.maps.model.PolygonOptions
import com.amap.api.maps.model.Polyline
import com.amap.api.maps.model.PolylineOptions
import com.amap.api.services.core.AMapException
import com.amap.api.services.geocoder.GeocodeResult
import com.amap.api.services.geocoder.GeocodeSearch
import com.amap.api.services.geocoder.RegeocodeResult
import com.emapp.lccode.R
import com.emapp.lccode.base.BaseActivity1
import com.emapp.lccode.base.EventBusConfig
import com.emapp.lccode.base.EventBusModel
import com.emapp.lccode.bean.FeatureCollection
import com.emapp.lccode.bean.Geometry
import com.emapp.lccode.bean.MapJsonDeserialize
import com.emapp.lccode.bean.UpLatLngKt
import com.emapp.lccode.databinding.ActivityPointMapBinding
import com.emapp.lccode.mode.ProjectMappointViewModel
import com.emapp.lccode.mode.ProjectViewModel
import com.emapp.lccode.utils.MapAppUtil
import com.emapp.lccode.utils.MmkvUtil
import com.emapp.lccode.utils.SettingUtil
import com.emapp.lccode.utils.getluJsonString
import com.emapp.lccode.utils.setOnclickNoRepeat
import com.emapp.lccode.utils.showMessage
import com.google.gson.GsonBuilder
import com.gyf.immersionbar.ktx.immersionBar
import com.hjq.permissions.OnPermissionCallback
import com.hjq.permissions.Permission
import com.hjq.permissions.XXPermissions
import com.hjq.toast.Toaster
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode


class MapPointActivity : BaseActivity1<ProjectMappointViewModel, ActivityPointMapBinding>(),
    AMap.OnMyLocationChangeListener, AMap.OnMarkerClickListener, AMap.OnPolylineClickListener,
    AMap.OnMapClickListener,
    GeocodeSearch.OnGeocodeSearchListener {
    private val aMap: AMap by lazy { mViewBind.mapView.map }
    var map_Polygon = ""//项目划区json文件名
    val geocoderSearch: GeocodeSearch by lazy { GeocodeSearch(this) }
    var lu: FeatureCollection? = null
    var count = 0
    override fun initView(savedInstanceState: Bundle?) {
        immersionBar {
            titleBar(mViewBind.lvTitle.ivBar)
            statusBarDarkFont(true)
            fullScreen(true)
            statusBarColor(R.color.transparent)
            navigationBarColor(R.color.white)
        }
        AMapLocationClient.updatePrivacyShow(this, true, true)
        AMapLocationClient.updatePrivacyAgree(this, true)
        geocoderSearch.setOnGeocodeSearchListener(this)
        mViewBind.mapView.onCreate(savedInstanceState)
        EventBus.getDefault().register(this)
       // map_Polygon = intent.getStringExtra("json_text").toString()
        map_Polygon = MmkvUtil.getString("json_text","")
        MmkvUtil.putString("json_text","")
        mViewBind.lvTitle.tvTitle.text = ""
        mViewBind.lvTitle.tvRight.visibility = View.GONE
        if (!SettingUtil.isLocationEnabled(this)) {
            showMessage(
                "手机定位服务未打开！",
                "温馨提示",
                "去开启",
                positiveAction = {
                    val settingsIntent = Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)
                    startActivity(settingsIntent)
                })
        }
        getPermission()
    }

    private fun getPermission() {
        XXPermissions.with(this)
            .permission(Permission.ACCESS_COARSE_LOCATION)
            .permission(Permission.ACCESS_FINE_LOCATION)
            .request(object : OnPermissionCallback {
                override fun onGranted(permissions: List<String>, all: Boolean) {
                    MmkvUtil.putBoolean("loc_permission", true)
                    setUpMapIfNeeded()
                    log_e("map_Polygon--" + map_Polygon)
                    lu = if (map_Polygon.isNullOrBlank()) {
                        null
                    } else {
                        val gson = GsonBuilder()
                            .registerTypeAdapter(Geometry::class.java, MapJsonDeserialize())
                            .create()
                        gson.fromJson(map_Polygon, FeatureCollection::class.java)
                    }
                    log_e("lu--" + lu.toString())
                    setData()
                }

                override fun onDenied(permissions: List<String>, never: Boolean) {}
            })
    }

    fun setData() {
        if (lu == null) return
        if (lu?.features == null) return
        mViewModel.viewModelScope.launch {
            withContext(Dispatchers.IO) {
                lu!!.features?.forEach { feature ->
                    if (feature?.geometry != null) {
                        count++
                        var lat: ArrayList<LatLng> = arrayListOf()
                        when (feature.geometry.type) {
                            "Polygon", "MultiLineString" -> {
                                val d =
                                    feature.geometry.coordinates as? ArrayList<ArrayList<ArrayList<Double>>>
                                d?.forEach { c ->
                                    lat.clear()
                                    c.forEach { e ->
                                        val l = MapAppUtil.other2Gao(
                                            this@MapPointActivity,
                                            LatLng(e[1], e[0])
                                        )
                                        lat.add(
                                            l
                                        )
                                        addMarker(l, mViewModel.markers.size)
                                    }
                                    lat.removeAt(0)
                                    //addPolygon(lat)
                                }
                            }

                            "MultiPolygon" -> {
                                val d=
                                    feature.geometry.coordinates as? ArrayList<ArrayList<ArrayList<ArrayList<Double>>>>
                                d?.forEach { c ->
                                    c.forEach { e ->
                                        lat.clear()
                                        e.forEach { f ->
                                            val l = MapAppUtil.other2Gao(
                                                this@MapPointActivity,
                                                LatLng(f[1], f[0])
                                            )
                                            lat.add(
                                                l
                                            )
                                            addMarker(l, mViewModel.markers.size)
                                        }
                                        lat.removeAt(0)
                                        // 绘制一个长方形
                                        //addPolygon(lat)
                                    }
                                }

                            }

                            "LineString" -> {
                                lat.clear()
                                val data =
                                    feature.geometry.coordinates as? ArrayList<ArrayList<Double>>
                                data?.forEach { c ->
                                    val l = MapAppUtil.other2Gao(
                                        this@MapPointActivity,
                                        LatLng(c[1], c[0])
                                    )
                                    addMarker(l, mViewModel.markers.size)
                                    lat.add(l)
                                    l.run {
                                        if (!mViewModel.guiji.contains(this)) {
                                            mViewModel.guiji.add(this)
                                            //  addLine()
                                        }
                                    }
                                }
                                addPolyline(lat)
                            }

                            else -> {
                                log_e("feature.geometry.type==" + feature.geometry.type)
                            }
                        }
                    }
                }
            }
        }
    }

    override fun createObserver() {
        mViewModel.run {
            map_project.observe(this@MapPointActivity) {

            }
        }
    }

    /**
     * 绘制项目区域
     */
    suspend fun addPolygon(lat: ArrayList<LatLng>) {
        val pOption =
            PolygonOptions().addAll(lat).strokeWidth(4f)
                .strokeColor(Color.argb(50, 1, 1, 1))
                .fillColor(Color.argb(30, 253, 1, 1))
        withContext(Dispatchers.Main) {
            mViewModel.polygons.add(aMap.addPolygon(pOption))
        }
    }

    /**
     * 绘制设备路线
     */
    private suspend fun addPolyline(lat: ArrayList<LatLng>) {
        val poly = PolylineOptions()
            .addAll(lat)
            .width(14f)
            .color(Color.RED)
        withContext(Dispatchers.Main) {
            mViewModel.polyline = aMap.addPolyline(poly)
        }

    }

    /**
     * 绘制设备路线
     */
    fun addMarkerLine(latLng: LatLng?, position: Int) {
        if (latLng == null) return
        latLng.run {
            if (!mViewModel.guiji.contains(this)) {
                mViewModel.guiji.add(this)
                addLine()
            }
        }
        val mark = MarkerOptions().anchor(0.5f, 1.0f)
            .snippet(position.toString())
            .position(latLng)
        // withContext(Dispatchers.Main) {
        mViewModel.markers.add(aMap.addMarker(
            mark
        ).apply { `object` = position })
        // }

    }

    suspend fun addMarker(latLng: LatLng?, position: Int) {
        if (latLng == null) return
        val mark = MarkerOptions().anchor(0.5f, 1.0f)
            .snippet(position.toString())
            .position(latLng)
        withContext(Dispatchers.Main) {
            mViewModel.markers.add(aMap.addMarker(
                mark
            ).apply { `object` = position })
        }

    }

    private fun setUpMapIfNeeded() {
        aMap.apply {
            isMyLocationEnabled = true
            setOnMyLocationChangeListener(this@MapPointActivity)
            setOnMapClickListener(this@MapPointActivity)
            moveCamera(CameraUpdateFactory.zoomTo(16f))
//            mapType = AMap.MAP_TYPE_SATELLITE // 卫星地图模式
            uiSettings.isZoomControlsEnabled = false
            uiSettings.isRotateGesturesEnabled = false
            uiSettings.isMyLocationButtonEnabled = false // 设置默认定位按钮是否显示
            setOnMarkerClickListener(this@MapPointActivity)
            setOnMapClickListener(this@MapPointActivity)
            setOnPolylineClickListener(this@MapPointActivity)
            myLocationStyle = MapAppUtil.setupLocationStyle(5)
        }
    }


    override fun onMyLocationChange(location: Location?) {
        if (location == null) {
            Toaster.show("定位失败，请检查您的定位权限")
            return
        }
        if (location.latitude == 0.0)
            return
        mViewModel.mylocation = location
        if (mViewModel.isRecordLine) {
            LatLng(location.latitude, location.longitude).run {
                if (!mViewModel.guiji.contains(this)) {
                    mViewModel.guiji.add(this)
                    addLine()
                }
            }

        }
        if (mViewModel.isFirstLoc && location.latitude > 0) {
            aMap.moveCamera(
                CameraUpdateFactory.newLatLng(
                    LatLng(
                        location.latitude,
                        location.longitude
                    )
                )
            )
            mViewModel.isFirstLoc = false
        }

    }

    /**
     * 录制轨迹
     */
    private fun addLine() {
        mViewModel.removeLine()
        val poly = PolylineOptions()
            .addAll(mViewModel.guiji)
            .width(12f)
            .color(Color.RED)
        //.setCustomTexture(BitmapDescriptorFactory.fromResource(R.drawable.map_l_guan))
        mViewModel.polyline = aMap.addPolyline(poly)
    }

    override fun onMarkerClick(p0: Marker?): Boolean {
        val position: Int = p0?.`object` as Int
        if (position != null) {
            log_e("position--$position")
        }
        return true
    }

    @SuppressLint("NewApi")
    override fun onPolylineClick(p0: Polyline?) {
    }


    @SuppressLint("CheckResult")
    override fun onBindViewClick() {
        setOnclickNoRepeat(
            mViewBind.lvTitle.ivLeft,
            mViewBind.lvTitle.tvRight,
            mViewBind.ivL,
            mViewBind.tvAdd,
            mViewBind.ivStart,
            mViewBind.ivEnd,
            mViewBind.ivDelete,
            mViewBind.ivDelete2,
            mViewBind.tvType,
            mViewBind.tvState,
            mViewBind.ivLoc
        ) {
            when (it.id) {
                R.id.iv_l, R.id.iv_left -> {
                    finish()
                }

                R.id.iv_loc -> {
                    if (mViewModel.mylocation != null && mViewModel.mylocation!!.latitude > 0) {
                        aMap.moveCamera(
                            CameraUpdateFactory.newLatLngZoom(
                                LatLng(
                                    mViewModel.mylocation!!.latitude,
                                    mViewModel.mylocation!!.longitude
                                ), 15f
                            )
                        )
                    }

//                    MaterialDialog(this@ProjectMapActivity).show {
//                        lifecycleOwner(this@ProjectMapActivity)
//                        customView(R.layout.dialog_pro_device)
//                        var name = getCustomView().findViewById<TextView>(R.id.tv_name)
//                        name.text = "测试"
//
//                    }
                }

                R.id.tv_add -> {
                    if (count > 1) {
                        Toaster.show("此数据包含多条路径，暂不支持手机端编辑")
                        return@setOnclickNoRepeat
                    }
                    var gson = getluJsonString(mViewModel.guiji)
                    if (mViewModel.guiji.isEmpty()) {
                        gson = ""
                    }
                    EventBus.getDefault().post(EventBusModel(EventBusConfig.SET_JSON_TEXT, gson))
                    finish()
                }

                R.id.iv_start -> {
                    mViewBind.run {
                        tvAdd.visibility = View.GONE
                        fvStart.visibility = View.VISIBLE
                        ivStart.visibility = View.GONE
                        ivEnd.visibility = View.VISIBLE
                        ivDelete.visibility = View.GONE
                    }

                    mViewModel.run {
                        guiji.clear()
                        isRecordLine = true
                        removeLine()
                    }
                }

                R.id.iv_end -> {
                    mViewBind.run {
                        tvAdd.visibility = View.VISIBLE
                        fvStart.visibility = View.GONE
                    }
                    mViewModel.isRecordLine = false
                    val gson = getluJsonString(mViewModel.guiji)
                    val intent =
                        Intent(this@MapPointActivity, ProjectAddKtActivity::class.java)
                    intent.putExtra("flag", "create")
                    //intent.putExtra("json_text", gson)
                    MmkvUtil.putString("json_text",gson)
                    intent.putExtra("project_id", mViewModel.project_id)
                    startActivity(intent)

                }

                R.id.iv_delete -> {
                    mViewBind.run {
                        tvAdd.visibility = View.VISIBLE
                        fvStart.visibility = View.GONE
                    }
                    mViewModel.removeLine()
                }

                R.id.iv_delete2 -> {
                    if (count > 1) {
                        Toaster.show("此数据包含多条路径，暂不支持手机端编辑")
                        return@setOnclickNoRepeat
                    }
                    if (mViewModel.guiji.isEmpty() || mViewModel.markers.isEmpty()) {
                        return@setOnclickNoRepeat
                    }
                    mViewModel.guiji.removeLast()
                    mViewModel.markers.removeLast().remove()
                    addLine()
                }
            }
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onEventMainThread(event: EventBusModel) {
        when (event.type) {
            EventBusConfig.REFRESH_PROJECT_DEVICE -> {
            }

            else -> {}
        }
    }


    override fun onResume() {
        super.onResume()
        mViewBind.mapView.onResume()
    }

    override fun onPause() {
        super.onPause()
        mViewBind.mapView.onPause()
    }

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        mViewBind.mapView.onSaveInstanceState(outState)
    }

    override fun onDestroy() {
        super.onDestroy()
        mViewBind.mapView.onDestroy()
        EventBus.getDefault().unregister(this)
    }

    override fun onMapClick(p0: LatLng?) {
        addMarkerLine(p0, mViewModel.markers.size)
//        mViewModel.viewModelScope.launch {
//            withContext(Dispatchers.IO) {
//                addMarker(p0, 1)
//            }
//        }

    }

    fun inProjectAir(p0: LatLng): Boolean {
        var have = false
        for (p in mViewModel.polygons) {
            if (p.contains(p0)) {
                have = true
                break
            }
        }
        return have
    }

    override fun onRegeocodeSearched(result: RegeocodeResult?, resultCode: Int) {
        dismissLoading()
        if (resultCode == AMapException.CODE_AMAP_SUCCESS && result != null) {
            val address = result.regeocodeAddress?.formatAddress
            val latlng = UpLatLngKt(
                mViewModel.mylocation!!.longitude,
                mViewModel.mylocation!!.latitude,
                address
            )
        } else {
            Toaster.show("定位失败")
        }
    }

    override fun onGeocodeSearched(p0: GeocodeResult?, p1: Int) {
    }

}